package com.linkallcloud.web.deapi;

import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson2.JSON;
import org.apache.logging.log4j.util.Strings;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.linkallcloud.core.dto.Result;
import com.linkallcloud.deapi.annotation.DeApi;
import com.linkallcloud.deapi.tuils.Encrypts;

public class DeResultWrapReturnValueHandler implements HandlerMethodReturnValueHandler {

    private final HandlerMethodReturnValueHandler delegate;
    private final String aeskey;

    public DeResultWrapReturnValueHandler(HandlerMethodReturnValueHandler delegate, String aeskey) {
        this.delegate = delegate;
        this.aeskey = aeskey;
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return delegate.supportsReturnType(returnType) || returnType.hasMethodAnnotation(DeApi.class);
    }

    @Override
    public void handleReturnValue(Object o, MethodParameter returnType, ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest) throws Exception {
        // .setRequestHandled(true)表示此函数可以处理请求，不必交给别的代码处理
        mavContainer.setRequestHandled(true);

        Object wrapo = o;
        if (returnType.hasMethodAnnotation(DeApi.class)) {
            DeApi deAPi = returnType.getMethodAnnotation(DeApi.class);
            if (deAPi.resultWrap()) {
                if (!(o instanceof Result)) {
                    wrapo = new Result<>(o);
                }
            }

            if (!Strings.isBlank(deAPi.encrypt()) && deAPi.encrypt().equalsIgnoreCase("AES")) {
                String encContent = Encrypts.encryptAES(JSON.toJSONString(wrapo), aeskey);
                webRequest.getNativeResponse(HttpServletResponse.class).getWriter().write(encContent);
                return;
            }
        }
        delegate.handleReturnValue(wrapo, returnType, mavContainer, webRequest);
    }

}
